Я сам разобрался с проблемой. Конечно тут две новые появились, но на них забью уже:
ИИ не нравился герой, из-за него вообще никто не нанимался.
ИИ посчитал, что улучшив главное здание, он лишается главного здания, а значит нужно его снова строить. То есть, например, улучшив ратушу до крепости, он считает, что ратуши больше нет и необходимо построить ещё одну. Потом он крепость улучшит до замка, посчитает, что разрушили крепость, улучшит до крепости ратушу№2, снова потеряет ратушу и построит уже третью.
Если вы хотите сделать нестандартный рудник для ИИ (не через триггеры) - забудьте. Лучше переделайте дефолтный, возможно где-то в коде нужно для ИИ прописать ID нового рудника, но никто не знает где :)
Эмм что за ерунда, сократил код, убрав всё лишнее, но утечки все равно остаются, по 1.5 - 2 хэндла за каждое нанесение урона (тип хэндла не знаю как посмотреть). Когда триггер отключаешь, то всё нормально.
Сокращенный код
function SDMSCreateTextTag takes nothing returns nothing
local unit u=GetTriggerUnit()
local unit s=GetEventDamageSource()
local integer i=GetConvertedPlayerId(GetOwningPlayer(u))
local texttag tt=CreateTextTag()
local real dmg=GetEventDamage()
if ( dmg > 1.00 ) and ( dmg < 9999.00 ) then
if GetPlayerId(GetOwningPlayer(u))==12 then
call SetTextTagText(tt, "|cff9db9eb-"+I2S(R2I(dmg))+"|r", 0.023)
else
call SetTextTagText(tt, "|cffffa500-"+I2S(R2I(dmg))+"|r", 0.023)
endif
call SetTextTagPosUnit(tt, u, 0)
call SetTextTagColor(tt, 255, 255, 255, 255)
call SetTextTagVelocity(tt, 0.05325*Cos(90 * bj_DEGTORAD), 0.05325*Sin(90 * bj_DEGTORAD))
call SetTextTagPermanent(tt, false)
call SetTextTagLifespan(tt, 1.0)
call SetTextTagFadepoint(tt, 0.0)
endif
call PolledWait(2.0)
call DestroyTextTag(tt)
set u=null
set s=null
set i=0
set dmg=0
set tt=null
endfunction
function SDMSTriggerRegisterUnitDamaged takes nothing returns nothing
call TriggerRegisterUnitEvent(udg_SDMStrigger,GetEnteringUnit(),EVENT_UNIT_DAMAGED)
endfunction
function theSDMSTriggerActions takes nothing returns nothing
local trigger UnitEnter=CreateTrigger()
call TriggerRegisterEnterRectSimple(UnitEnter, gg_rct_Arena)
call TriggerAddAction(UnitEnter,function SDMSTriggerRegisterUnitDamaged)
set UnitEnter=null
endfunction
function InitTrig_the_SDMS_Trigger takes nothing returns nothing
local trigger tr=CreateTrigger()
set udg_SDMStrigger=CreateTrigger()//Тут также меняется название глобальной переменной типа триггер.
call TriggerAddAction(udg_SDMStrigger,function SDMSCreateTextTag)
call TriggerRegisterTimerEventSingle(tr,0.0)
call TriggerAddAction(tr,function theSDMSTriggerActions)
set tr=null
endfunction
Wait вызывает утечки ((
Пришлось делать через таймер
Это какие-то извращения у вас там.
Bj можно раскрыть и увидеть, что там происходит присваивание нового юнита глобалке bj_lastCreatedUnit.
Нужно сразу присваивать локалке нового юнита и не использовать эти ваши bj_lastCreatedUnit:
local unit u
u = CreateUnitAtLoc (GetTriggerPlayer(), 'hfoo', location, bj_UNIT_FACING)
В моей карте игроки вместе играют на острове "полном жизни". И если крипов по типу волка или медведя не будет на локации, то он окажется слишком уж пустым.
С координатной функцией юнит также завис.(
Решить проблему так и не смог, теперь просто тыкаю юнита-игрока в систему рывков, чтобы тот сбежал от крипа.
Шо за дерьмо! По изощеренне то не мог удаление эффектов сделать? видел код этих вейтов, там наверняка лимит операций уже... Да и вовсе не надо использовать вейты для задержек, уже все изсписано - ненадо вейтов, небудет ничего работать хоть вы обосритесь, есть хештаблица + таймер, забудьте про вейты, за одно и баги связанные с ними...
у легионки в доте 12 абилок, по степеням двойки + 1 +2 +4 и так далее, макс бонус 512 ед. Системы которые повышают некоторые параметры юнитов подобным образом выкладывались 100500 раз, не вижу причин не юзать поиск.
Если вам 1 раз за игру надо апнуть атаку и у героя нету морфов и прочего говна, подойдут руны на доп дмг - они повышают белую атаку, но стоит морфнутся и бонуса нету.
Ребята, я разобрался
Триггер работает нормально и безутечно, вся проблема в том, что создавая спелл-активатор с кислотной бомбы, я указал интервал урона = 0.00, что и повлекло все лаги
И в чём смысл делать глобалку, а не просто писать тогда уж сразу GetFilterUnit( )
Я сдеал локалку, чтобы вместо GetFilterUnit( ) писать то, что мне нужно, в данном случае CLONE quq_CCCP:
Потом клонов от способностей ищут не так,
Да так и я их могу найти
Точнее не совсем так, я их искал через Юнит входит в Область ( Игровая зона )
Но искать их в другом триггере и сдругим событием мне нафиг не нужно.
Мне нужно найти иллюзии сразу в триггере со способностью, чтобы потом не было геморроя
========================
И ещё раз повторюсь, что при повторном использовании способности, 2 прошлые иллюзии (да и вообще в принципе если рядом с гером будут другое любое ко-во иллюзий) перемещаются к противнику. Но две новосозданные остаются на месте.
Так же повторюсь, что когда проверка была IsUnitIllusion == false, то иллюзии определяло как не иллюзии!
Все кто пытались помочь, похоже проигнорировали это замечание...
========================
Мой вывод таков: Иллюзиям, призванным через стандартную Способность (Предмет: Иллюзии) присваивается статус иллюзий слегка позже, чем происходит проверка.
С другой стороны, скорее всего это может и можно как-то обойти, ведь есть карты примеры, где подобное работает нужным образом.
О том, как устроены чёртовы способности близов стоит только догадываться =\
К счастью Способность (Предмет: Иллюзии) не наносит 0.00 урона, и за это близам огромное спасибо (что у меня в очередной раз не бомбануло)
А вообще, проще по-моему сделать свою игру, чем нормальную карту в варкрафте -_-
фатал после игры может быть вызван
а) использованием malloc
б) копированием внутриигровых структур (например, структуру сплеша перенес от одного юнита другому, при чистке один раз адрес зачистился, а на втором проходе произошел краш)
в) неизвестным мне образом
Наверное, тупо опять считывание силы атаки чудило: у доспеха ее не было, он фаталил при приближении к нему героя с аурой "жечь врагов в % от своей атаки + % от их атаки". Ща снова из-за этого апдейт перепиливаю.
Правда, не помню, был ли в той игре, кроме Матери-Земли, и этот вот другой герой... но пока остановимся на том, что у доспеха причина фатала была одна, если будет снова фаталить именно с доспехом - вернёмся к теме.
Тестил, тестил. Думал найду ошибку. Короче не знаю в чем дело, видимо и в правду баг. Решил по-другому. Ловить поставку, и ловить продажу. То есть ловить то, что пришло, и то, что ушло.
событием - "юнит закладывает в лавку" (EVENT_PLAYER_UNIT_PAWN_ITEM) ловим продажу итемов.
GetSellingUnit() =продающий торговец (типа всякие предметы закладывает в магазин и получает деньги)
GetBuyingUnit()=GetTriggerUnit() = покупающий торговец (это обычно магазин)
событием - "юнит закладывает из лавки (продает артефакт)" (EVENT_PLAYER_UNIT_SELL_ITEM) ловим покупку итемов
GetSellingUnit()=GetTriggerUnit()=продающий торговец (обычно это магазин)
GetBuyingUnit() = покупающий торговец (наш герой получает артефакты)
Решил, я по-своему. Короче, видимо, итем в магазине исчезает при добавлении. Попробовал запоминать все добавленные итемы, и при добавлении я сначала удалю всё в магазине, а потом заново добавлю. Пришлось, еще порядок (номер слотов) запоминать, а то строятся ключи хэша на строгом порядке. Если возьму и заберу итем посередине, придется заново выстраивать порядок. Не знаю, пока тестил много времени, пока без косяков. Главное, что работает. Меня это радует. Но пока не буду спешить. Мне бы хотелось затестить норм.
SсRealm, есть 2 нейтральных (12 и 15) и 2 резервных(13 и 14) игрока
в доте 6-6 используются резервные для крипов сторон
для крипов в лесу используется 12 игрок
у меня просто нет слов
это не стол заказов
и точно не место для размещения своего скайпа
не говоря уже о том что вопрос поднимался в статьях раз 10 как минимум
Ребята, я разобрался
Триггер работает нормально и безутечно, вся проблема в том, что создавая спелл-активатор с кислотной бомбы, я указал интервал урона = 0.00, что и повлекло все лаги
Это делается в триггерах. В триггере "Иниц. сражения" за это отвечает действие "Режим сражения - Set starting resourses (for all players)". Просто удали это действие и стартовое количество ресурсов при запуске тогда будет равно нулю.
там ничего сложного нет. вопрос часто встречаемый в последнее время. Там периодически перебирают всех юнитов. В основном работа в группе. Многие неправильно работать в группе, забывают ее удалять.
Вариант 1 (общий вариант)
Событие - периодический таймер
действие - цикл перебираем всех игроков
действие - установить "группа DDD = выбрать всех юнитов в группу игрока" //я использовал такой необычный способ, чтобы группу запомнить в глобалку, также используй фильтр/условие, отсеивай не нужных юнитов (например, не здания)
действие - ForGroup (делать действие над каждым юнитом в группе DDD), и в зависимости от типа юнита складывай / прибавляй денежки игроку // if-ами придеться перебирать, если ...
группу не забываем удалять после работы с нею. Можно использовать также счетчики, и использовать заранее заготовленную группу, в нее будем добавлять и убавлять юнитов. при завершении постройки добавляй юнита в группу, при уничтожении удаляй из группы. И не нужно будет каждый раз пересоздавать группу и удалять.
Вариант 2
Событие - юнит вошел в зону
условие - юнит является зданием
события можно по-другому найти, так как вошел в зону не совсем точное, потому, что юнит вошел, то есть его только , что создали. Он в данный момент только строится
Событие - юнит завершает строительство
действие - if/then/else //короче длинные будут проверки типов, так как будут разные здания, и разные здания будут давать разные денежки
условие - тип юнита
действие - переменная + 1 // общий голд
когда здание уничтожают, убавляем голда
Событие - юнит умирает или покидает зону
условие - тип юнита
действие - переменная - 1
когда улучшают здание
Событие - юнит завершает улучшение
условие - тип юнита
действие - переменная + еще 1
начисляем периодически
Событие - Периодический таймер
действие - добавить голда
Вариант 3
далее предлагаю запоминать сколько дает данное здание. Можно использовать Custom Value / обычное значение юнита, в котором можно сохранить число. Число можно хранить у юнита, у каждого оно свое. В этом числе можно сохранить сколько оно денежек дает. Есть две функции SetCustomValue - установить число, и GetCustomValue - условие, определяющее сколько золота.
условие - тип юнита
действие - SetCustomValue
и потом периодически перебираем всех юнитов
Событие - Периодический таймер
действие - Выбрать всех юнитов в группу, и сделать действия. //перебирает каждого юнита, и добавляем столько, сколько GetCustomValue у юнита
Использовать хранения можно также хэш-таблицу. Ваше CustomValue может использоваться в других системах, и поэтому нужны еще где-то запоминать, а хэш-таблица самое то.Не забудь глобалку хэша создать, и создать хэш-таблицу в начале игры
Событие - Инициализация
Действие - Создать/инициализровать хэш-таблицу
Действие - установить глобалка = последняя созданная хэш-таблица
при сохранении используется так
CS: set udg_D=GetHandleId( ваш юнит) //целочисленное число, HandleId - номер объекта, необходим для дальнейшего
сохранить целочисленное число Integer
Хэш-таблица - Сохранить целочисленное число, Id-хэндл, и ключ //там есть типа адрес и номер, адрес - как хэндл. номер - ключ, ключ вводишь любой
при загрузке хэндла
CS: set udg_D=GetHandleId( ваш юнит)
Хэш-таблица - Загрузить число по хэндлу, и ключу //ключ вводишь тот, который ввел при сохранении
Хэш-таблица используется точно также как и число у юнита, мы всех юнитов перебираем узнаем кол-во число, складываем и даем бабло. Также можно использовать классификацию юнита (можно триггерно дабавлять/удалять) xgm.guru/p/wc3/wc3targets
Качаем систему ссыль и каждые 0.5 сек. проверяем кол-во золота у игрока и устанавливаем ему бонус урона, таймер и триггер следящий за смертью персонажа (нельзя модифицировать параметры мертвым) который включается при изучении умения.
зажми кнопку shift и лишь потом кликай по полю которое надо поменять
и пиши туда что хочешь
а вообще подобных вопросов овер дофига
учитесь использовать поиск
Во внутреннем представлении (читай: "после отработки препроцессора JassHelper") любая структура есть набор массивов с индексом, по которому лежат данные именно этой структуры во всех связанных массивах. По факту, передавая структуру в качестве аргумента функции, ты передаёшь только её id из массива.
По поводу вопроса: полного перевода vJass мануала на русский язык не существует в природе, так что вот ссылка на английский: www.wc3c.net/vexorian/jasshelpermanual.html Крайне рекомендую пользоваться не базовым синтаксисом, а C-подобным, который обеспечивает "AdicHelper" aka cJass (ссылка на русскую версию мануала), это позволит в будущем гораздо проще перейти к программированию на полноценных языках.
orc01, есть событие EventUnitsInRange, делаешь триггер, а при постройки башни добавляешь в него это событие для каждой башни, в условиях проверяешь что тот кто подошел нужного тебе типа юнит, ну действия думаю проблем не вызовут...
лол что?
скорость работы глобалок в 1,5 раза быстрее чем у хештейблов
т.е. 10 обращений к хештейблам выполняется столько же времени сколько и 15 к глобалкам
если каждую секунду не выполняется более 1000 обращений к хештейблу то не юзать хэштейблы ради оптимизации та ещё тупость
ты знаешь начальные хп декораций
ты можешь отловить факт приказа добывать дерево и OrderTargetDestructable
ты можешь перезаписывать этот триггер каждый раз, как юнит получает новый приказ, хотя хз, как оно себя ведет при смене дерева
нормального способа задетектить урон по не-юнитам нет
SetUnitPosition довольно тяжелая операци, юзайте SetUnitX\Y в конце полета юзай SetUnitPosition для того чтобы юнит не залетел в непроходимое место.
Фильтр просто ужас, ну кто так фильтры делает?
Проверка на 'Aloc', я в ужасе на кой черт проверять на дамми если GropEnumUnitsInRange\Rect не выделяет москитов, тока EnumOfPlayer может пикнуть москитов, остальное не пикает их, на то они и москиты...
Вот как выглядит нормальный фильтр без локалок и прочего
function EnemyFilter takes nothing returns boolean
set bj_lastFilterUnit = GetFilterUnit( )
return GetUnitState( bj_lastFilterUnit, UNIT_STATE_LIFE ) > 0.405 and IsUnitEnemy( bj_lastFilterUnit, bj_groupEnumOwningPlayer ) and not( IsUnitType( bj_lastFilterUnit, UNIT_TYPE_MAGIC_IMMUNE ) or IsUnitType( bj_lastFilterUnit, UNIT_TYPE_MECHANICAL ) or IsUnitInvulnerable( bj_lastFilterUnit ) )
endfunction
UnitDamageTargetEx - красиво но нафиг ненужно обводить в отдельную функцию с тучей аргументов + жутко неудобно, 100500 аргументов у функции и фиг знает за что какой от вечает, прямо так UnitDamageTarget, без отдельной функции.
Туча констант, тоже хорошо тока длят наработок, на деле ставь конкретные значения или юзай Difine vjass'a.
Bornikkeny, сделал специально чтобы доказать тебе что ты несёшь бред
даже 2 скрина приложил
думаю закинуть библиотеки сможешь сам (в папку *твой jngp*\AdicHelper\lib)
Хорошо группы реализуешь как альтернативу unit[array]. Я тоже самое получил. nvc123, и всё же твой хук не тот что мне нужен.
Я решил проблему, спасибо что дал идею обрабатывать движение внутри структуры, а не в стеке.
кот
library Hook initializer Init_Hook uses LibMath
globals
mhook ahook[100]
integer ihook = -1
endglobals
struct mhook
unit host = null
unit target = null
real face = 0
real speed = 0
real dis = 0
real dismax = 0
integer chaini = 0
unit chain[50]
real scale = 0
integer move = 1
integer i = 0
static method Create takes unit host, real tx, real ty, real scale returns mhook
local mhook h = mhook.create()
local integer i = GetPlayerId(GetOwningPlayer(host))
local real x = GetUnitX(host)
local real y = GetUnitY(host)
local real f = GetAngleXY(x,y,tx,ty)
set h.host = host
set h.face = f
set h.speed = 600
set h.dismax = 1400
set h.scale = scale
set h.chain[0] = CreateUnit(Player(i),'h007',GetPolarX(GetUnitX(host),f,h.scale/2),GetPolarY(GetUnitY(host),f,h.scale/2),f)
set h.i = i
call UnitAddAbility(h.chain[0],'Amrf')
call UnitAddAbility(h.chain[0],'Amrf')
call SetUnitFlyHeight(h.chain[0],50,0)
call SetUnitPathing(h.chain[0],false)
return h
endmethod
method Start takes nothing returns boolean
if ihook < 1000 then
set ihook = ihook + 1
set ahook[ihook] = this
return true
else
return false
endif
endmethod
method Destroy takes nothing returns nothing
local integer i = 0
loop
exitwhen i > ihook
if ahook[i] == this then
set ahook[i] = ahook[ihook]
set ahook[ihook] = 0
set ihook = ihook - 1
set i = ihook // выход из цикла
endif
set i = i + 1
endloop
set this.target = null
set this.host = null
call this.destroy()
endmethod
method Move takes nothing returns nothing
local integer i1 = 0
local integer l = 0
local real x
local real y
local real xh
local real yh
local real f
if move == 1
set dis = dis + speed*0.025
loop
exitwhen i1 > .chaini
set x = GetUnitX(.chain[i1])
set y = GetUnitY(.chain[i1])
if i1 > 0 then
set f = GetAngleXY(x,y,GetUnitX(.chain[i1-1]),GetUnitY(.chain[i1-1]))
call SetUnitX(.chain[i1],GetPolarX(x,f,.speed*0.025))
call SetUnitY(.chain[i1],GetPolarY(y,f,.speed*0.025))
else
set f = face
call SetUnitX(chain[i1],GetPolarX(x,f,.speed*0.025))
call SetUnitY(chain[i1],GetPolarY(y,f,.speed*0.025))
endif
call SetUnitFacing(chain[i1],f)
set i1 = i1 + 1
endloop
set x = GetUnitX(chain[chaini])
set y = GetUnitY(chain[chaini])
set f = GetAngleXY(GetUnitX(.host),GetUnitY(.host),x,y)
set xh = GetPolarX(GetUnitX(.host),f,.scale/2)
set yh = GetPolarY(GetUnitY(.host),f,.scale/2)
//Create==================
if GetDisXY(xh,yh,x,y) >= .scale/2 then
set chaini = chaini + 1
set chain[chaini] = CreateUnit(Player(.i),'h007',xh,yh,f)
call UnitAddAbility(.chain[.chaini],'Amrf')
call UnitAddAbility(.chain[.chaini],'Amrf')
call SetUnitFlyHeight(.chain[.chaini],50,0)
endif
if dis > dismax then
set move = 0
endif
else
//REVERSE=============
set xh = GetUnitX(host)
set yh = GetUnitY(host)
set chain[chaini+1] = host
loop
exitwhen l > chaini
set x = GetUnitX(chain[l])
set y = GetUnitY(chain[l])
//if chain[chaini] == null then
// set f = GetAngleXY()
//endif
set f = GetAngleXY(x,y,GetUnitX(chain[l+1]),GetUnitY(chain[l+1]))
call SetUnitX(chain[l],GetPolarX(x,f,speed*0.025))
call SetUnitY(chain[l],GetPolarY(y,f,speed*0.025))
call SetUnitFacing(chain[l],f-180)
set l = l + 1
endloop
//Destroy==================
set x = GetUnitX(chain[chaini])
set y = GetUnitY(chain[chaini])
set xh = GetUnitX(host)
set yh = GetUnitY(host)
if GetDisXY(GetUnitX(chain[chaini]),GetUnitY(chain[chaini]),GetUnitX(host),GetUnitY(host)) < 100 then
call RemoveUnit(chain[chaini])
set chain[chaini] = null
set chaini = chaini - 1
if chaini == -1 then
call .Destroy()
endif
endif
endif
endmethod
endstruct
private function Engine takes nothing returns nothing
local integer i = 0
local mhook h
local group g
local unit t
loop
exitwhen i > ihook
if ahook[i] != 0 then
set h = ahook[i]
//--run--//
call h.Move()
else
set ahook[i] = ahook[ihook]
set ahook[ihook] = 0
set ihook = ihook - 1
set i = i - 1
endif
set i = i + 1
endloop
//call DestroyGroup(g)
set g = null
set t = null
endfunction
function Trig_HookC_Bool takes nothing returns boolean
if GetSpellAbilityId() == 'A01D' then //Способность Мясной хук
return true
else
return false
endif
endfunction
function Trig_HookC_Actions takes nothing returns nothing
local mhook h
set h = mhook.Create(GetSpellAbilityUnit(),GetSpellTargetX(),GetSpellTargetY(),110)
call h.Start()
endfunction
function Init_Hook takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddAction( t, function Trig_HookC_Actions )
call TriggerAddCondition(t,function Trig_HookC_Bool)
call TimerStart(CreateTimer(),0.025,true,function Engine)
endfunction
endlibrary
любой штатный способ быстрее любого велосипеда. группа будет быстрее перебора массива юнитов. переменная лучше, чем постоянные GetFilterUnit()
если дашь мне код в чистом жассе, я могу прямо в лайве замеры сделать
скачай этот файл и закинь его в папку AdicHelper\lib\ в папке с jngp
после в шапке карты напиши include "ifdebug.j"
и создай триггер с событием
игрок написал в чат ifdebug как точное совпадение
действие
кастом скрипт log()
после чего запусти карту и напиши в чат ifdebug
он выведет на экран все if/else/elseif через которые он прошёл (true в скобках в конце строки означает что значение в ифе истина)
Скачай новую версию TESH с HIVE, удали папку tesh в папке JNPG, вместо неё распакуй туда скачанную. В блокноте пишешь свои функции, сохраняешь в папку tesh\includes. Если в это время открыт редактор, то в меню Trigger Editor кликаешь TESH -> Reload user includes, и твои функции начинают подсвечиваться. Формат подсветки можно настроить в Options, что над рабочей областью редактора.
Аргументы функций не обязательно обнулять Steal nerves:
нет, не нужно. это аргументы (это тоже локалки), говорят, что обнуляется само по завершению функции. А то что объявляем через local надо обнулять. строки вообще не обязательно обнулять (хоть не шарю в этом программировании, но обнулять не нужно). Уже многие пишут не надо строки обнулять, и аргументы. Можешь поискать.
Нужно обнулять только те локалки, которые указывают на игровой обьект.
ограничить число найма можно, есть спец. функции. Поищи в действии в вкладке игрок, установить (макс. геои)
лимит на определенный тип. лень искать. это уже было поищи в интернете
удалить и добавить можно триггерно. В разделе нейтральное здание. Есть одно условие, что если в РО изначально выставлен на продажу, то триггерно не удалишь, и не поменяешь. Нужно триггерно добавлять.
еще можно скрыть героя у данного игрока, не помню есть ли такая функция. Это наподобие как у абилок, видит один игрок, в то время другой вообще не видит. Просто есть продажа, а есть найм. не путать.
короче удаляешь и подменяешь новым и все
8gabriel8, стандартные порталы как раз включаются триггером, так же триггерно им можно назначать области телепорта, так же они не ломают карту путей.
Насчет упираются в здание, карту путей ставь от портала, физ размер в 0.
Так ты же выключаешь триггер на 18 секунд вот он и не срабатывает.
Поставь условие, что герыч не имеет абилки-пустышки, если не имеет - дать её и через 18 сек забрать и пустить молнию.
Правда я не уверен насчёт того, отловится ли attacking unit через 18 сек вейта, проверь...
Вообще, если устраивает орбом - то даёшь "сферу молний" с эффектом "цепь молний", у которой 18 сек перезарядка(у цепи не у сферы)
Делаешь способность пустышку на основе "Канал", далее делаешь триггер с событием "Юнит начал направлять способность" в условиях ставишь
свою способность, а в действиях условиями на наличие предметов делаешь крафт. Всё что я тут написал - это отсылка к темам которые можно самому найти.
Итак, вроде получилось!
1.Создаём шесть активных предметных способностей не делающих ничего, но имеющих долгую перезарядку.
2.Создаём шесть предметов, которым указываем каждому свою из предыдущих способностей в поля "B) Способности - Способности (iabi)" и "F) Характеристики -Название (icid)".
3.Для сброса перезарядки предметов на герое последовательно даём и запускаем герою все шесть предметов.
4.Не забываем о перезрядке самого предмета - заменяем на новую копию.
5.Теоретически (не пробовал) при использовании очень долгих периодов может быть достаточно использовать героем по разу пять предметов с кд скажем двое суток, а потом для очистки героя от кд предметов запускать только один предмет с кд сутки.
Sebra2, потестил
у предмета есть поле cooldownId
на русском называется характеристики - название (не путать с Текст - название где задаётся название предмета)
у тех предметов у которых это поле совпадает один кулдаун
Большое СПАСИБО!
пы сы, Надеюсь, выбрав свой ответ как лучший, не украду ни у кого "опыт".
И в правду рак мозга...
Статьи почитать не судьба? Некоторые предметные способности не повышают уровень - точнее эффект от повышения уровня не изменяется, посему делают 5 (100500) способностей с разными бонусами и выдаются юниту в нужный момент.
Способность маски соби - повышает базовый реген маны и бонус от интеллекта, так что крипам с 0 манарегена эта способность ничего не добавит.
там 2 баффа, для ближнего и дальнего боя. Ты поменял 1 из баффов, а другой не поменял, все дела.
Просто можно откопировать его в строке баффов и написать 2 раза.
Было создано 22 366 679 экземпляров класса CUnitListNode, которые заняли 255.9 МБ памяти.
При очередной попытке выделения, игра упала.
Виной всему утечки памяти: за 21 минуту набралось 80 тысяч групп и 20 тысяч точек.
Также, из-за выполнения большого количества кода, сильно лагает.
На стадии выбора героя (первые две минуты), выполняется 550 000 операций в секунду, а далее — 1 200 000.
Для сравнения: лимит потока — 300 000 операций.
Хорошо, что ты приложил карту, так как в логе маловато информации.
Через что уничтожаешь? Если через килл, то конечно умирает и нейтральный.
Если наносить от какого-то даммика урон в мильены, то не умрет нейтральный.
Можно от даммика развеяние нежити за 0.01 сек.
Заменять можно, внося значение золота в переменную и потом, создавая новый рудник, ставить количество золота в него из переменной, благо это даже в ГУИ реализовано.
Верни стандартную функцию создания стартовых юнитов, поставь игровую паузу, замени всех юнитов на свои аналоги, возобнови игру (я так же дополнительно прячу всех юнитов на этот период). Не забудь удалить все проклятые/оплетённые рудники, если нужно. Чтобы заново оплести рудник после замены юнитов (если заменял древа жизни), используй триггер "Боевая единица - (приказ без цели) Оплести ближайший рудник" (перед оплетением поставь паузу 0.1 секунды чтобы после удаления успел заново появится оригинальный рудник).
В нем я сначала витаскиваю древо с земли и сразу спецально его сажу в землю и приказиваю немедленно оплести рудник, после через n секунд я его витаскиваю и приказиваю идти в другое место и через n секунд его сажаю в землю. Все работает без проблем, древо послушное как раб.
Открываешь доту, выбираешь путь сохранения в Сохранить как, жмёшь Восстановить. Правда, не факт, что всё нормально восстановиться и будет работать, как надо. Попробовал сейчас доту восстановить, но чего-то не хочет она загружаться в редакторе. Войск почти нет, редактор страшно тормозит. Наверное, как-то иначе её надо взламывать. Если что, на сайте wc3-maps были взломанные доты.
Карта с нестандартными молниями и описанием. Смотреть Readme в менеджере импорта.
Если тебе типа фиолетовой молнии рубика надо, то вот есть вроде этого
Ну цепь молний можно прилепить, в сферу замедления засунуть обычную цепную молнию.
Ну а так, разумеется без триггеров низя. эффект молний это такой спрайт от цели до цели, а не 3д снаряд, поэтому там где молния не придусмотренна так сделать нельзя.
Насчет наработок - детект физического урона + библиотека для движения молний ( забыл как называется), нл суть в том что это достаточно сложно и на jass, для новичков эту тему лучше не трогать а ограничится стандартными способностями.
ну вокруг цели пикаешь всех врагов в группу, саму цель сразу из нее исключаешь, выбираешь случайного нового врага из группы на расстоянии перескока молнии от последнего пораженного, бьешь его следующей молнией и удаляешь из группы, ну и повторять так, сколько надо отскоков или пока группа не будет пустой.
Лимит операций, обычно это беда настигает заядлых гуишников.
На jass обычно нету таких проблем.
Создайте таймер с периодом .00 сек и запускайте им функции инициализации триггеров.
функция типа InitTrig_Имя триггера - это функция инициализации триггера, она вызывается из функции InitCustomTriggers, но если этих вызовов очень много то функция упирается в лимит операций и поток завершается так и не создав все триггеры.
ограничить число найма можно, есть спец. функции. Поищи в действии в вкладке игрок, установить (макс. геои)
лимит на определенный тип. лень искать. это уже было поищи в интернете
удалить и добавить можно триггерно. В разделе нейтральное здание. Есть одно условие, что если в РО изначально выставлен на продажу, то триггерно не удалишь, и не поменяешь. Нужно триггерно добавлять.
еще можно скрыть героя у данного игрока, не помню есть ли такая функция. Это наподобие как у абилок, видит один игрок, в то время другой вообще не видит. Просто есть продажа, а есть найм. не путать.
короче удаляешь и подменяешь новым и все
» WarCraft 3 / Как убрать на панели приказов кнопку?
» WarCraft 3 / Боты ничего не строят
» WarCraft 3 / PolledWait
» WarCraft 3 / Лимит символов
» WarCraft 3 / Дот урон
» WarCraft 3 / Расшифровка
» WarCraft 3 / Еще фатал после игры
» WarCraft 3 / Продажа вещей
» WarCraft 3 / Как сделать способность, зависящую от статов?
» WarCraft 3 / Массив отрядов
» WarCraft 3 / Количество золота
» WarCraft 3 / Хештаблица
» WarCraft 3 / Отлов цели приказа
» WarCraft 3 / Какой путь для иконки?
» WarCraft 3 / Функция Atan2
» WarCraft 3 / Операции сравнения
» WarCraft 3 / Функции
» WarCraft 3 / Автокаст на здания
» WarCraft 3 / Предметы
» WarCraft 3 / Повышение уровня способности триггерно
» WarCraft 3 / Странные ошибки
» WarCraft 3 / Нестандартный проклятый рудник в ИИ не строится
» WarCraft 3 / Древа
» WarCraft 3 / Молнии
» WarCraft 3 / Снова эти функции